<?php


namespace App\Kuafu\User\Controller\Merchant;


use App\Exceptions\BaseException;
use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Config\Service\ConfigService;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\Sms\Service\SmsService;
use App\Kuafu\User\Enum\CodeEnum;
use App\Kuafu\User\Enum\UserCodeEnum;
use App\Kuafu\User\Enum\UserEnum;
use App\Kuafu\User\Exceptions\AuthException;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\User\Model\UserRoleMapping;
use App\Kuafu\User\Service\UserBindService;
use App\Kuafu\User\Service\AuthService;
use App\Kuafu\User\Service\UserService;
use App\Kuafu\User\Validate\UserValidate;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Kuafu\File\FileUtil;

class UserController extends BaseController
{

    public function getUserInfo(Request $request)
    {
        $authUser = AuthService::getAuthUser();
        $shopId = (int)$request->header('shopId', 0);
        if ($authUser['status'] != 0) {
            return $this->fail(UserCodeEnum::ERR_USER_STATUS, UserCodeEnum::CODE_TEXT[UserCodeEnum::ERR_USER_STATUS]);
        }

        // 增加白名单采集用户行为
        $sentryConfig  = ConfigService::getConfigDetail("merchantSentry", "sentry");
        $sentryUserIds = attributeGet($sentryConfig, "value.userIds", []);

        $return = [
            'id'                    => $authUser['id'],
            'username'              => preg_replace('/\d+$/', '', $authUser['username']),
            'mobile'                => $authUser['mobile'],
            'status'                => $authUser['status'],
            'avatar'                => FileUtil::domain() . '/' . (strlen($authUser['avatar']) ? $authUser['avatar'] : UserEnum::DEFAULT_AVATAR),
            'wechatId'              => $authUser['wechatId'],
            'address'               => (string)Shop::query()->where('id', $shopId)->value('address'),
            'createdAt'             => $authUser['createdAt'],
            'isManager'             => UserRoleMapping::checkUserRole(
                $this->brandId, $shopId, $authUser['id'], config('merchant.manager_role_id'),
            ),
            'isCollectUserBehavior' => in_array($authUser['id'], $sentryUserIds)
        ];
        return $this->success($return);
    }

    /**
     * 合并了用户信息和用户名下店铺信息的接口
     * @param Request $request
     * @return JsonResponse
     */
    public function getUserInfoShopLists(Request $request)
    {
        $user = $this->getUserInfo($request);
        $userResponse = json_decode($user->getContent(), true);
        if ($userResponse['code'] == 200) {
            $userResponse['data']['shopLists'] = ShopService::userShopLists($userResponse['data']['id']);
        }

        return $this->success($userResponse['data']);
    }

    public function setUserInfo(Request $request)
    {
        $this->validate($request, [
            'avatar' => 'required|string|max:128',
            'wechatId' => 'sometimes|string|max:64',
        ]);
        $authUser = AuthService::getAuthUser();
        if ($authUser['status'] != 0) {
            return $this->fail(UserCodeEnum::ERR_USER_STATUS, UserCodeEnum::CODE_TEXT[UserCodeEnum::ERR_USER_STATUS]);
        }
        $path = (string)parse_url($request->avatar, PHP_URL_PATH);
        $authUser->avatar = ltrim($path, '/');
        $authUser->wechatId = (string)$request->wechatId;
        $authUser->save();
        return $this->success();
    }

    /**
     * 修改用户密码
     * @param Request $request
     * @return JsonResponse
     * @throws UserException
     */
    public function setUserPassword(Request $request)
    {
        $user = AuthService::getAuthUser();
        SmsService::verifyCode($user['mobile'], $request->code, SmsService::CODE_TYPE_MODIFY_PASSWORD);
        UserService::setUserPassword($user['id'], $request->password);
        //修改密码后重新登陆
        AuthService::logout();
        return $this->success();
    }

    /**
     * 修改用户手机号码
     * @param Request $request
     * @return JsonResponse
     * @throws UserException
     */
    public function setUserMobile(Request $request)
    {
        SmsService::verifyCode($request->mobile, $request->code, SmsService::CODE_TYPE_MODIFY_MOBILE);
        $userId = AuthService::getUserId();
        UserService::setUserMobile($request->mobile, $userId);
        //修改手机号重新登陆
        AuthService::logout();
        return $this->success();
    }

    /**
     * 非登录忘记密码
     * @param Request $request
     */
    public function forgetPassword(Request $request)
    {
        $user = UserService::getUserValue('mobile', $request->mobile, ['id']);
        if (!$user) {
            return $this->fail(UserCodeEnum::ERR_USER_NOT_EXIST,
                UserCodeEnum::CODE_TEXT[UserCodeEnum::ERR_USER_NOT_EXIST]);
        }
        UserService::setUserPassword($user['id'], $request->password);
        SmsService::verifyCode($request->mobile, $request->code, SmsService::CODE_TYPE_FORGET_PASSWORD);
        return $this->success();
    }

    /**
     * 新增员工基本信息
     * @param Request $request
     * @return JsonResponse
     * @throws UserException
     */
    public function addStaffInfo(Request $request)
    {
        $mobileExist = (int)$request->get("mobileExist", 0);
        if ($mobileExist) {
            $valid = UserValidate::addStaffInfoByMobileExist($request);
        } else {
            $valid = UserValidate::addStaffInfo($request);
        }
        if ($valid) {
            return $this->fail(UserCodeEnum::ERR_USER_NOT_INPUT, $valid);
        }
        $info = UserService::addUserInfo(
            $request->username,
            $request->mobile,
            $request->inShop,
            $request->positions,
            $request->induction,
            $request->idCardFacePhoto,
            $request->idCardBackPhoto,
            $request->healthPhoto,
            $request->healthPhotoDate,
            $request->header('shopId'),
            $request->header('brandId'),
            AuthService::getUserId()
        );
        return $this->success($info);
    }

    /**
     * 编辑员工基本信息
     * @param Request $request
     * @return JsonResponse
     * @throws UserException
     */
    public function setStaffInfo(Request $request)
    {
        $valid = UserValidate::setStaffInfo($request);

        if ($valid) {
            return $this->fail(UserCodeEnum::ERR_USER_NOT_INPUT, $valid);
        }
        $info['userId'] = UserService::setStaffInfo(
            $request->userId,
            $request->username,
            $request->mobile,
            $request->inShop,
            $request->positions,
            $request->induction,
            $request->idCardFacePhoto,
            $request->idCardBackPhoto,
            $request->healthPhoto,
            $request->healthPhotoDate,
            $request->header('shopId'),
            $request->header('brandId'),
            AuthService::getUserId(),
            $request->status,
        );
        return $this->success($info);
    }

    //绑定用户设备唯一ID
    public function bindingRegistrationId(Request $request)
    {
        //根据用户ID绑定registrationId
        $userId = AuthService::getUserId();
        return $this->success(UserBindService::bindRegistrationId($userId, $request->get('registrationId')));
    }

    /**
     * 用户信息 & 当前门店是否有访问权限
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ShopException
     * @throws AuthException
     * @throws UserException
     * @throws GuzzleException
     */
    public function getUserinfoWithShopAuth(Request $request): JsonResponse
    {
        $shopId = (int)$request->header("shopId", 0);
        $payload  = AuthService::getPayload()->toArray();
        $isStaff  = isset($payload["thirdLoginType"]) && $payload["thirdLoginType"];
        return $this->success(UserService::getUserinfoWithShopAuth($shopId, $isStaff));
    }

    /**
     * 根据手机号查询用户名
     * @param Request $request
     * @return JsonResponse
     */
    public function getUserInfoByMobile(Request $request): JsonResponse
    {
        $mobile = (string)$request->get("mobile", '');
        $userId = AuthService::getUserId();
        return $this->success(UserService::getUserInfoByMobile($userId, $mobile));
    }

    /**
     * 健康证识别
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     * @throws ValidationException
     */
    public function healthCardOcr(Request $request): JsonResponse
    {
        $this->validate($request, [
            'file' => 'required|string'
        ]);

        $file = (string)$request->post('file');

        $data = UserService::healthCardOcr($file);

        return $this->success($data);
    }

    /**
     * 修改员工状态
     * @throws ValidationException|UserException
     */
    public function updateStatus(Request $request): JsonResponse
    {
        $this->validate($request, [
            'status' => 'required|int',
            'userId' => 'required|int',
        ]);

        $shopId    = (int)$request->header("shopId", 0);
        $status    = (int)$request->post('status');
        $userId    = (int)$request->post('userId');
        $rmsUserId = AuthService::getUserId();

        if ($userId == $rmsUserId && $status == CodeEnum::USER_STATUS_STOP) {
            return $this->fail(400, '不可对自己操作离职');
        }

        UserService::updateStatus($shopId, $userId, $status, $rmsUserId);

        return $this->success();
    }


    /**
     * 离职评价
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException|UserException
     */
    public function leaveEvaluate(Request $request): JsonResponse
    {
        $this->validate($request, [
            'score'           => 'required|integer',
            'userId'          => 'required|integer',
            'evaluateContent' => 'required|string',
        ]);

        $score           = (int)$request->post('score');
        $userId          = (int)$request->post('userId');
        $evaluateContent = (string)$request->post('evaluateContent');
        $shopId          = (int)$request->header('shopId');

        UserService::leaveEvaluate($score, $userId, $evaluateContent, $shopId, AuthService::getUserId());

        return $this->success();
    }
}
